import re
import json
from django.conf import settings
from django.shortcuts import HttpResponse
from django.utils.deprecation import MiddlewareMixin
from django.http import JsonResponse


class URLAccessMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 白名单路径（无需权限）
        WHITE_LIST = getattr(settings, 'URL_WHITE_LIST', [
            r'^/acc/auth/login/$',
            r'^/acc/auth/loginView/$',
            r'^/acc/auth/sms_send_code/$',
            r'^/acc/auth/sms_verify_code/$',
            r'^/logout/$',
            r'^/api/.*',
            r'^/static/.*',
            r'^/media/.*',
            # r'^',
        ])

        current_path = request.path_info

        # 白名单直接放行
        for pattern in WHITE_LIST:
            if re.match(pattern, current_path) or current_path == '/':
                return self.get_response(request)

        # 登录验证?next={current_path}用户尝试访问的页面,碰到未登录进行登录后,再返回到current_path这个页面
        # if not request.user.is_authenticated:
        #     return redirect(f'acc/auth/login/?next={current_path}')

        # 权限验证django_content_type
        if not self.has_permission(request):
            return HttpResponse('无权限访问此页面', status=403)

        return self.get_response(request)

    def has_permission(self, request):
        # 获取用户所有URL权限
        # user_perms = request.user.user_permissions.values_list('codename', flat=True)  # 直接权限+自定义权限
        user_perms = request.user.get_all_permissions()  # 包含用户权限+组权限
        # print('user_perms:', user_perms)
        if 'jewelry.access_account_page' in user_perms:  # 对应models中定义的权限
            return True
        return False


class CustomStatusMiddleware(MiddlewareMixin):
    def process_response(self, request, response):
        """修改210状态码为200
            过来的是: return Response({"error": "手机号格式错误", "status_origin": 210}, status=210)
            response.status_code是后边的status=210,本身有可能是400等错误信息
            然后把response.status_code改为200,那么前端接收到都会是response.ok或者result.success=True
            所以在前端成功里面需要再判断result.success,区分真正的成功 和 假的成功
        """
        if response.status_code == 210:  # 210一般是需文档说明,这里用作不让控制台输出错误提示
            response.status_code = 200

        # 仅处理状态码非200的响应（根据实际需求调整）
        if 400 <= response.status_code < 600:
            try:
                # 解析响应内容为字典
                response_data = json.loads(response.content)

                # 1. 当错误信息以detail返回时:
                if response_data.get('detail'):
                    # 执行自定义逻辑（例如日志记录、状态码修正等）
                    print(f"中间件捕获到错误：{response_data}")
                    # response.status_code = 200  # 欺骗前后端控制台
                    # response.status_origin = 210  # 供前端确定是错误信息
            except json.JSONDecodeError:
                pass  # 非JSON响应则不处理
        return response

    # def __call__(self, request):
    #     print("接收request:", request)
    #     print("接收到头:", request.headers)  # 验证传输层
    #     if 'HTTP_X_REQUESTED_WITH' in request.META:
    #         request.session['IS_AJAX'] = True
    #     return self.get_response(request)
